using System;
using System.Collections.Generic;
using System.Text;


namespace PW.Mini.SlepowronskiJ.Siec.Aktywacja
{
    /// <summary>
    /// funkcja aktywacji tangens hiperboliczny unipolarny
    /// </summary>
    /// <remarks>
    /// Definicja unipolarny tanh funkcji aktywacji
    /// <code>
    ///          e^(2x) - 1                 e^(2x)          1
    /// f(x) = ----------------  +0.5 = -------------- = -----------
    ///         2*( e^(2x) + 1 )          (e^(2x)+1)     (1+e^(-2x))
    /// 
    ///           2 e^(2x)          
    /// f`(x) = ------------- = 2* f(x) * (1-f(x))
    ///         (e^(2x)+1)^2
    /// </code>     
    /// </remarks>

    [Serializable]
    class UnipolarTanhFunkcjaAktywacji : IFunkcjaAktywacji
    {


        public UnipolarTanhFunkcjaAktywacji()
            : base()
        {
            nazwa = "Tanh";
            rodzajPolarnosci = SKALOWANIE_UNIPOLARNE;
        }

        /// <summary>
        /// Clone the object.
        /// </summary>
        /// <returns>The cloned object.</returns>
        public override object Clone()
        {
            return new UnipolarTanhFunkcjaAktywacji();
        }


        /// <summary>
        /// <code>
        ///          e^(2x) - 1                 e^(2x)          1
        /// f(x) = ----------------  +0.5 = -------------- = -----------
        ///         2*( e^(2x) + 1 )          (e^(2x)+1)     (1+e^(-2x))
        /// </code>
        /// </summary>
        /// <param name="x">x</param>
        /// <returns>f(x)</returns>
        public override double WartoscFunkcji(double x)
        {
            return (double)(1/(1+Math.Exp(-2*x)));
        }

        /// <summary>
        /// <code>
        ///           2 e^(2x)          
        /// f`(x) = ------------- = 2* f(x) * (1-f(x))
        ///         (e^(2x)+1)^2
        /// </code>
        /// </summary>
        /// <param name="x">x</param>
        /// <returns>f'(x)</returns>
        public override double WartoscPochodnejFunkcji(double x)
        {
            double fx = WartoscFunkcji(x);
            return 2 * fx * (1-fx);
        }

        /// <inheritdoc />
        public override double DerivativeFunction(double b, double fx)
        {
            return 2 * fx * (1 - fx);
        }
    }
}
